package chapter05;

import java.util.LinkedList;

/**
 * @author chisheng
 * @since 2021-11-11
 */
public class EventQueue {

    private final int maxEvent;

    static class Event {
    }

    private final LinkedList<Event> eventQueue = new LinkedList<>();

    private final static int DEFAULT_MAX_EVENT = 10;

    public EventQueue() {
        this(DEFAULT_MAX_EVENT);
    }

    public EventQueue(int maxEvent) {
        this.maxEvent = maxEvent;
    }

    public void offer(Event event) {
        synchronized (eventQueue) {
            // 队列已满
            while (eventQueue.size() >= maxEvent) {
                try {
                    console("the queue is full!");
                    // 阻塞生产者线程，等待消费者线程消费后唤醒阻塞的生产者线程
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            // 事件队列未满，事件入队
            console("the new event is submitted!");
            eventQueue.addLast(event);
            // 唤醒一个消费者线程
            eventQueue.notify();
        }
    }

    public Event take() {
        synchronized (eventQueue) {
            // 队列为空
            while (eventQueue.isEmpty()) {
                try {
                    System.out.println("the queue is empty!");
                    // 阻塞消费者线程，等待生产者线程生产后唤醒消费者线程
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            // 事件队列不为空，事件出队
            Event event = eventQueue.removeFirst();
            console("the event " + event + " is handled.");
            // 唤醒一个生产者线程
            eventQueue.notify();
            return event;
        }
    }

    private void console(String message) {
        System.out.printf("%s: %s%n", Thread.currentThread().getName(), message);
    }

}
